<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <title>宠物自动合并与孵化</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            display: flex;
            height: 100vh;
            font-family: 'Segoe UI', sans-serif;
            background: #f7f9fb;
            color: #333;
        }

        .left-panel {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            display: flex;
            flex-direction: column;
        }

        .right-panel {
            width: 460px;
            padding: 20px;
            border-left: 1px solid #ddd;
            background: #ffffff;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
        }

        .input-section {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }

        .input-section input {
            padding: 6px;
            flex: 1;
        }

        .controls,
        .speed-select {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }

        .controls button,
        .speed-select button {
            padding: 8px 14px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
        }

        .controls button {
            background-color: #4a90e2;
            color: white;
        }

        .controls button:hover {
            background-color: #357abd;
        }

        .speed-select button {
            background: #eee;
            color: #333;
            border: 1px solid #aaa;
        }

        .speed-select button.active {
            background: #4caf50;
            color: white;
        }

        .egg-info {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            gap: 6px;
            margin-bottom: 20px;
        }

        .egg-box {
            background: #fff;
            border: 1px solid #ccc;
            padding: 8px 10px;
            border-radius: 6px;
            min-width: 100px;
            text-align: left;
            position: relative;
        }

        .egg-box.highlight {
            background: #fffbe6;
            color: #d33;
            animation: pulse 0.4s;
        }

        .egg-change {
            position: absolute;
            top: 4px;
            left: 100%;
            margin-left: 6px;
            color: red;
            font-size: 14px;
            font-weight: bold;
            animation: floatOut 1s ease-out forwards;
        }

        .pet-stats-box {
            margin-top: 10px;
            margin-bottom: 20px;
            border: 1px solid #ccc;
            border-radius: 6px;
            padding: 10px;
            background-color: #f9f9f9;
            max-width: 300px;
            font-size: 13px;
        }

        .pet-stats-box table {
            width: 100%;
            border-collapse: collapse;
            text-align: center;
        }

        .pet-stats-box th {
            background-color: #f0f0f0;
            padding: 4px 6px;
            font-weight: bold;
            border-bottom: 1px solid #ccc;
        }

        .pet-stats-box td {
            padding: 4px 6px;
            border-bottom: 1px solid #eee;
        }

        .pet-stats-box tr:last-child td {
            border-bottom: none;
        }

        .pet-stats-box td:nth-child(2) {
            color: #0077cc;
        }

        .pet-stats-box td:nth-child(3) {
            color: #cc3300;
        }

        .pet-layout {
            display: flex;
            gap: 30px;
            align-items: flex-start;
            margin-top: 20px;
            padding: 10px;
            border: 1px dashed #ccc;
            border-radius: 8px;
            background: #fafafa;
        }

        .pet-stats-box {
            flex-shrink: 0;
            width: 180px;
            font-size: 13px;
        }

        .pet-stats-box table {
            width: 100%;
            border-collapse: collapse;
            text-align: center;
        }

        .pet-stats-box th {
            background-color: #f0f0f0;
            padding: 6px;
            font-weight: bold;
            border-bottom: 1px solid #ccc;
        }

        .pet-stats-box td {
            padding: 6px;
            border-bottom: 1px solid #eee;
        }

        .pet-stats-box tr:last-child td {
            border-bottom: none;
        }

        .pet-layout-wrapper {
            display: flex;
            justify-content: center;
            margin-top: 20px;
            padding: 10px 0;
        }

        .pet-layout {
            display: flex;
            gap: 30px;
            align-items: flex-start;
            padding: 20px;
            border: 1px dashed #ccc;
            border-radius: 8px;
            background: #fafafa;
            max-width: 900px;
            width: 100%;
        }

        .pet-stats-box {
            flex-shrink: 0;
            width: 180px;
            font-size: 13px;
        }


        @keyframes floatOut {
            0% {
                opacity: 1;
                transform: translateY(0);
            }

            100% {
                opacity: 0;
                transform: translateY(-20px);
            }
        }

        @keyframes pulse {
            0% {
                transform: scale(1);
            }

            50% {
                transform: scale(1.1);
            }

            100% {
                transform: scale(1);
            }
        }

        .log {
            background: #1e1e1e;
            color: #d4d4d4;
            font-family: Consolas, monospace;
            padding: 12px;
            height: 700px;
            overflow-y: auto;
            font-size: 14px;
            border-radius: 6px;
            white-space: pre-wrap;
            box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
        }

        .pet-grid,
        .battle-row {
            display: grid;
            gap: 16px;
            /* 增大间隙 */
            justify-content: center;
        }

        .battle-row {
            grid-template-columns: repeat(3, 120px);
            margin-bottom: 20px;
        }

        .pet-grid {
            grid-template-columns: repeat(4, 120px);
        }

        .pet {
            width: 120px;
            height: 120px;
            border-radius: 8px;
            text-align: center;
            font-size: 12px;
            padding: 5px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            position: relative;
            transition: transform 0.3s, background 0.3s;
        }

        .pet:hover {
            transform: scale(1.05);
        }

        .pet.q1 {
            background: #e3f2fd;
            border: 2px solid #64b5f6;
        }

        .pet.q2 {
            background: #d0f0c0;
            border: 2px solid #81c784;
        }

        .pet.q3 {
            background: #fff9c4;
            border: 2px solid #ffd54f;
        }

        .pet.q4 {
            background: #ffe0b2;
            border: 2px solid #ffb74d;
        }

        .pet.q5 {
            background: #ffccbc;
            border: 2px solid #ff8a65;
        }

        .pet.q6 {
            background: #d1c4e9;
            border: 2px solid #9575cd;
        }

        .pet.q7 {
            background: #f8bbd0;
            border: 2px solid #f06292;
        }

        .pet .exp-flag {
            position: absolute;
            top: 4px;
            right: 4px;
            background: red;
            color: white;
            font-size: 10px;
            padding: 2px 4px;
            border-radius: 4px;
        }

        .flash {
            animation: flashAnim 1s ease-in-out;
        }

        @keyframes flashAnim {
            0% {
                background-color: yellow;
            }

            100% {
                background-color: inherit;
            }
        }

        svg.arrow-line {
            position: absolute;
            top: 0;
            left: 0;
            pointer-events: none;
            z-index: 999;
        }
    </style>
</head>

<body>

<!-- 左侧操作区 -->
<div class="left-panel">
    <div class="input-section">
        <input id="accountInput" placeholder="账号 account" value="10000009">
        <input id="uidInput" placeholder="用户 UID" value="1876920565504348160">
    </div>

    <div class="controls">
        <button onclick="startProcess()">开始</button>
        <button onclick="pauseProcess()">暂停</button>
        <button onclick="manualRefresh()">刷新页面</button>
    </div>

    <div class="speed-select">
        <span>速度：</span>
        <button onclick="setSpeed(0)" id="speed0">最快</button>
        <button onclick="setSpeed(500)" id="speed1">中速</button>
        <button onclick="setSpeed(1000)" id="speed2" class="active">最慢</button>
    </div>

    <!-- 🧩 宠物展示与统计横向布局 -->
    <div class="pet-layout-wrapper">
        <div class="pet-layout">
            <div id="petStats" class="pet-stats-box"></div>
            <div>
                <div class="battle-row" id="battleRow"></div>
                <div class="pet-grid" id="petGrid"></div>
            </div>
        </div>
    </div>

</div>


<!-- 右侧：蛋数量 + 日志输出 -->
<div class="right-panel">
    <div>
        <h3 style="text-align:center;">蛋的数量</h3>
        <div class="egg-info" id="eggInfo"></div>
    </div>
    <div>
        <h3>日志输出</h3>
        <div class="log" id="log"></div>
    </div>
</div>

<!-- SVG 箭头连线定义 -->
<svg id="arrowSvg" class="arrow-line" width="100%" height="100%">
    <defs>
        <marker id="arrow" markerWidth="10" markerHeight="10" refX="6" refY="3" orient="auto"
                markerUnits="strokeWidth">
            <path d="M0,0 L0,6 L9,3 z" fill="red"/>
        </marker>
    </defs>
</svg>

<!-- 声音提示（需用户交互后才允许播放） -->
<audio id="mergeSound" preload="auto"
       src="https://assets.mixkit.co/sfx/preview/mixkit-arcade-retro-jump-223.wav"></audio>
<audio id="hatchSound" preload="auto"
       src="https://assets.mixkit.co/sfx/preview/mixkit-game-ball-tap-2073.wav"></audio>
<script>
    let paused = true;
    let speed = 2000;
    let petList = [];
    let previousEggs = {};
    const baseUrl = 'https://api-inke.huancaihz.com/api/v1';
    const arrowSvg = document.getElementById("arrowSvg");
    const mergeSound = document.getElementById("mergeSound");
    const hatchSound = document.getElementById("hatchSound");

    const sleep = ms => new Promise(r => setTimeout(r, ms));

    const log = msg => {
        const logBox = document.getElementById('log');
        const logs = logBox.innerHTML.split('<br>').filter(line => line.trim() !== '');
        logs.push(`➤ ${msg}`);
        while (logs.length > 100) logs.shift(); // 只保留最新100条
        logBox.innerHTML = logs.join('<br>') + '<br>';
        logBox.scrollTop = logBox.scrollHeight;
    };


    function setSpeed(ms) {
        speed = ms;
        document.querySelectorAll('.speed-select button').forEach(btn => btn.classList.remove('active'));
        const id = ms === 0 ? 'speed0' : ms === 500 ? 'speed1' : 'speed2';
        document.getElementById(id).classList.add('active');
    }

    function getHeaders() {
        return {
            'access-token': 'tuling',
            'account': document.getElementById('accountInput').value,
            'platform-code': 'Inke',
            'uid': document.getElementById('uidInput').value
        };
    }

    async function fetchPetList() {
        const res = await fetch(`${baseUrl}/pet/list`, {headers: getHeaders()});
        return res.json();
    }

    function drawArrow(fromEl, toEl) {
        arrowSvg.innerHTML = '';
        const fromRect = fromEl.getBoundingClientRect();
        const toRect = toEl.getBoundingClientRect();
        const x1 = fromRect.left + fromRect.width / 2;
        const y1 = fromRect.top + fromRect.height / 2;
        const x2 = toRect.left + toRect.width / 2;
        const y2 = toRect.top + toRect.height / 2;
        const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
        line.setAttribute("x1", x1);
        line.setAttribute("y1", y1);
        line.setAttribute("x2", x2);
        line.setAttribute("y2", y2);
        line.setAttribute("stroke", "red");
        line.setAttribute("stroke-width", "2");
        line.setAttribute("marker-end", "url(#arrow)");
        arrowSvg.appendChild(line);
    }

    function clearArrow() {
        arrowSvg.innerHTML = '';
    }

    function renderPets(pets, unlockedPetSlots) {
        const grid = document.getElementById('petGrid');
        const battle = document.getElementById('battleRow');
        grid.innerHTML = '';
        battle.innerHTML = '';
        petList = pets;
        const sorted = [...pets].sort((a, b) => a.pos - b.pos);
        const battlePets = [1, 2, 3].map(pos => sorted.find(p => p.pos === pos));

        const totalSlots = unlockedPetSlots + 3;
        const benchPets = Array.from({length: totalSlots - 3}, (_, i) => sorted.find(p => p.pos === i + 4));

        battlePets.forEach(p => battle.appendChild(createPetDiv(p)));
        benchPets.forEach(p => grid.appendChild(createPetDiv(p)));

        renderPetStats(pets);

    }

    function renderPetStats(pets) {
        const statsDiv = document.getElementById('petStats');
        const normal = {};
        const exp = {};

        pets.forEach(p => {
            const key = p.quality;
            if (p.is_exp_pet) {
                exp[key] = (exp[key] || 0) + 1;
            } else {
                normal[key] = (normal[key] || 0) + 1;
            }
        });

        const allQualities = [1, 2, 3, 4, 5, 6, 7];
        let html = '<table><tr><th>品质</th><th>普通</th><th>经验兽</th></tr>';
        allQualities.forEach(q => {
            html += `<tr><td>Q${q}</td><td>${normal[q] || 0}</td><td>${exp[q] || 0}</td></tr>`;
        });
        html += '</table>';
        statsDiv.innerHTML = html;
    }

    function createPetDiv(pet) {
        const div = document.createElement('div');
        if (pet) {
            div.className = `pet q${pet.quality}`;
            div.dataset.id = pet.id;
            div.dataset.pos = pet.pos;
            div.innerHTML = `ID:${pet.id}<br>Q${pet.quality} ${pet.quality_name}<br>${pet.is_exp_pet ? '经验兽' : '普通'}<br>Lv${pet.level}<br>EXP:${pet.exp}<br>Pos:${pet.pos}`;
            if (pet.is_exp_pet) {
                const flag = document.createElement('div');
                flag.className = 'exp-flag';
                flag.innerText = 'EXP';
                div.appendChild(flag);
            }
            div.onclick = () => alert(`宠物详情\nID: ${pet.id}\n品质: ${pet.quality_name}\n等级: ${pet.level}\n经验: ${pet.exp}\n位置: ${pet.pos}`);
        } else {
            div.className = 'pet';
            div.textContent = '空位';
        }
        return div;
    }

    function renderEggs(eggs) {
        const eggDiv = document.getElementById('eggInfo');
        eggDiv.innerHTML = '';
        eggs.forEach(e => {
            const diff = previousEggs[e.quality] !== undefined ? e.num - previousEggs[e.quality] : 0;
            previousEggs[e.quality] = e.num;
            const div = document.createElement('div');
            div.className = 'egg-box';
            if (diff !== 0) div.classList.add('highlight');
            div.textContent = `Q${e.quality}: ${e.num}`;
            if (diff !== 0) {
                const change = document.createElement('div');
                change.className = 'egg-change';
                change.textContent = `${diff > 0 ? '+' : ''}${diff}`;
                div.appendChild(change);
            }
            eggDiv.appendChild(div);
        });
    }
</script>
<script>
    async function changePetPosition(petId, targetPos) {
        const petElem = document.querySelector(`[data-id='${petId}']`);
        const targetElem = document.querySelector(`[data-pos='${targetPos}']`);
        if (petElem && targetElem) {
            drawArrow(petElem, targetElem);
        }
        await fetch(`${baseUrl}/pet/change/pet/position`, {
            method: 'POST',
            headers: {...getHeaders(), 'Content-Type': 'application/json'},
            body: JSON.stringify({pet_id: petId, target_pos: targetPos})
        });

        // 移动后立即刷新界面
        const data = await fetchPetList();
        renderPets(data.data.pets, data.data.unlocked_pet_slots);
        renderEggs(data.data.eggs);

        mergeSound.load();
        mergeSound.play();
        log(`移动宠物 ${petId} 到位置 ${targetPos}`);
        if (speed > 0) await sleep(800);
        clearArrow();
    }


    async function hatchEgg(quality) {
        const res = await fetch(`${baseUrl}/pet/egg/hatch`, {
            method: 'POST',
            headers: {...getHeaders(), 'Content-Type': 'application/json'},
            body: JSON.stringify({quality})
        });
        const result = await res.json();
        if (result.code === -1001) {
            log('孵化失败：宠物格子不足');
            return null;
        }

        hatchSound.load();
        hatchSound.play();
        log(`孵化 Q${quality} 蛋成功`);

        // 孵化后立即刷新界面
        const data = await fetchPetList();
        renderPets(data.data.pets, data.data.unlocked_pet_slots);
        renderEggs(data.data.eggs);

        return result;
    }


    async function mergeAndHatchLoop() {
        while (!paused) {
            const data = await fetchPetList();
            const pets = data.data.pets;
            const eggs = data.data.eggs;
            const maxSlots = data.data.unlocked_pet_slots + 3;
            renderPets(pets, data.data.unlocked_pet_slots);
            renderEggs(eggs);

            let canContinue = false;
            for (let i = 0; i < pets.length; i++) {
                for (let j = 0; j < pets.length; j++) {
                    if (i !== j) {
                        const p1 = pets[i], p2 = pets[j];
                        if (p1.quality === p2.quality && p1.quality < 7) {
                            await changePetPosition(p1.id, p2.pos);
                            canContinue = true;
                            break;
                        }
                        if (p1.is_exp_pet && !p2.is_exp_pet) {
                            await changePetPosition(p1.id, p2.pos);
                            canContinue = true;
                            break;
                        }
                    }
                }
                if (canContinue) break;
            }

            if (!canContinue && pets.length < maxSlots) {
                const eggToHatch = eggs.filter(e => e.quality <= 7 && e.num > 0).sort((a, b) => a.quality - b.quality)[0];
                if (eggToHatch) {
                    const result = await hatchEgg(eggToHatch.quality);
                    if (result) canContinue = true;
                    if (speed > 0) await sleep(speed);
                }
            }

            if (!canContinue) {
                log('没有可以合并或孵化的操作了');
                break;
            }

            if (speed > 0) await sleep(speed);
        }
    }

    function startProcess() {
        if (paused) {
            paused = false;
            log('开始自动处理...');
            mergeAndHatchLoop();
        }
    }

    function pauseProcess() {
        paused = true;
        log('已暂停');
    }

    // // 初始显示
    // fetchPetList().then(data => {
    //     renderPets(data.data.pets, data.data.unlocked_pet_slots);
    //     renderEggs(data.data.eggs);
    // });
</script>

<script>
    // 自动保存 account 和 uid
    window.addEventListener('DOMContentLoaded', () => {
        const savedAccount = localStorage.getItem('savedAccount');
        const savedUid = localStorage.getItem('savedUid');
        if (savedAccount) document.getElementById('accountInput').value = savedAccount;
        if (savedUid) document.getElementById('uidInput').value = savedUid;


        // 加这段：启动时自动发请求
        fetchPetList().then(data => {
            renderPets(data.data.pets, data.data.unlocked_pet_slots);
            renderEggs(data.data.eggs);
            log('页面已初始化并拉取最新宠物数据');
        });
    });

    document.getElementById('accountInput').addEventListener('input', e => {
        localStorage.setItem('savedAccount', e.target.value);
    });

    document.getElementById('uidInput').addEventListener('input', e => {
        localStorage.setItem('savedUid', e.target.value);
    });

    function manualRefresh() {
        fetchPetList().then(data => {
            renderPets(data.data.pets, data.data.unlocked_pet_slots);
            renderEggs(data.data.eggs);
            log('页面已刷新');
        });
    }
</script>


<!-- SVG 箭头定义（务必放在 body 里以供 marker 引用） -->
<svg style="position: absolute; width: 0; height: 0;">
    <defs>
        <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6"
                orient="auto-start-reverse">
            <path d="M 0 0 L 10 5 L 0 10 z" fill="red"/>
        </marker>
    </defs>
</svg>


</body>

</html>